package com.tedu.api.io;

import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * RandomAccessFile解决：File  无法实现的读写操作
 *
 * RandomAccessFile类：随机访问文件类
 * 功能：实现文件、文件夹的读写操作，底层使用C语言，底层：二进制数据
 *创建随即访问文件类
 * RandomAccessFile   raf=new RandomAccessFile("路径+文件全称"，“rw”)
 * RandomAccessFile   raf=new RandomAccessFile("路径+文件全称"，“r”)
 * 第二个参数【mode 模式】 ：r  模式--->该文件可以读操作
 *                      ：rw  模式--->该文件可以读写操作
 * 需求：实现   CV   复制音乐/视频
 */

public class RandomAccessFileAPI {
    @Test
    public void testRAE() throws IOException {
        //RandomAccessFile 对象创建出来 ---路径+全称  |模式：”rw“
        RandomAccessFile raf=new RandomAccessFile("raf.txt","rw");
        //1.在  API   项目文件夹下  创建raf.txt  文件   并且实现读写操作

        //计算机  识别：二进制   0000  0000
        /**
         * 需要raf.txt 写出一个  a字符
         * write(整数 ：a---十进制（转换为计算机二进制）：97     八进制   二进制)
         * 范围：0~255      ASCII码    二进制-----十进制----字母
         *                                      97        a
         *                                       98       b
         * 作用：在文件中写出一个字节  抛出IO流异常：存在写出失败情况
         *         整数的低八位写出到文件中
         *         一字节==8位二进制    0000   0001    1
         *                            0000   0010    2
         *                            0000   0011    3
         *                            0000   0110          6
         *         1024字节==1KB
         *         1024KB ==1MB
         *         1024MB ==1G
         *         1024G  ==1T
         */
        raf.write(97);   //写出一个字节 ，识别二进制，  写十进制转二进制
        raf.write(98);
        raf.write(101);
        //write方法---一个字节一个字节的写出
        //关闭流   close()
        raf.close();
    }
    /**
     * read()
     * 作用：读取一个字节，返回于十进制int类型返回，如果文件读到-1，代表结束
     *存在异常：IO流异常，读取可能会失败~
     */
    @Test
    public void testRead() throws IOException {
        //创建对象：随机访问文件对象--只读---raf.txt文件的内容
        RandomAccessFile raf=
                new RandomAccessFile("raf.txt","r");
       int i= raf.read();//“a”---ASCII码---97
        int j=raf.read();//"b"---ASCII码---98
        int q=raf.read();//“e”---ASCII码---101
        int y=raf.read();// “-1”---代表   文件没有数据

        System.out.println(i+" "+j+" "+q+" "+y);
    }
    /**
     * RAF类---构造器实现：读写操作---
     *                          -write(数值)   read()    一个字节一个字节写出以及读入
     *要求：复制粘贴一个音乐   【Version  1---不考虑效率】
     */
    @Test
    public void testCV() throws IOException {
        //1.源文件--“小跳蛙.mp3”---复制--操作：  读
        RandomAccessFile src=new RandomAccessFile("小跳蛙.mp3","r");
        //2.复制文件--“新跳蛙.mp3”---粘贴---擦作：  写出
        RandomAccessFile desc=
                new RandomAccessFile("新跳蛙.mp3","rw");
        //3.用于保存读写到字节  作用：①保存一个字节
        //                        ②-1代表文件读取到末尾
        int data=-1;
        //4.从“小跳蛙.mp3”中一个字节一个字节读取---  while循环(true){}
        // 同时一个字节一个字节写出“新跳蛙.mp3“
        //  (date=src.read())!=-1      作为条件判断语句
       long star=System .currentTimeMillis();
       //获取当前系统的毫秒数
        while((data=src.read())!=-1){//一个字节一个字节---读
            // 同时一个字节一个字节写出“新跳蛙.mp3“
            desc.write(data);
        }
        long end=System.currentTimeMillis();
        System.out.println("复制粘贴花费多少："+(end-star)+"毫秒");
    }
    /**
     * 需求：复制粘贴一个音乐   【Version 1~考虑效率】
     * 一个字节一个字节读取---一个字节一个字节写出【慢】
     * 100KB读取--一100KB写出   【快】
     *
     */
    @Test
    public void testCVS() throws IOException {
        //1.从“小跳蛙.mp3”---读取数据【100KB】
        RandomAccessFile src=new RandomAccessFile("小跳蛙.mp3","r");
        //2.从API目录下写出“效率高.mp3“---写出数据【100KB】
        RandomAccessFile desc=new RandomAccessFile("效率高.mp3","rw");
        //3.保存每次读取字节量    作用：①覆盖：保存读写数据，保障数据稳定性
        //                          ②没有文件：表示文件读取到末尾
        int len=-1;
        //4.效率：100KB    字节 byte
        byte[] data=new byte[1024*100];//100KB
//5.一直   从src文件中读取数据：100KB   |read(byte[] b)  读100KB
 // 5.1      src.read(byte[] data)       从src"小跳蛙.mp3"  一个字节一个字节的读
 // 5.2      src.read(byte[]data)        从src"小跳蛙.mp3"   100KB的读
 //5.3       len=src.read(byte[] data)    保存从src"小跳蛙.mp3" 100KB的读
 //5.4       （len=src.read(byte[] data)）!=-1    [复制判断条件]
 //            将读到100KB的字节数据保存len中，只要不等于-1，没有读完，一直读
        long star=System.currentTimeMillis();
        while((len=src.read(data))!=-1){
            //同时，读文件同时，写出数据write
            //write(整数)写出一个字节【慢】
            //write(字节数组,0,-1)  写出字节数组指定单位量【例：100KB】)
            desc.write(data,0,len);



        }
        long end=System.currentTimeMillis();
        System.out.println("100KB复制版本："+(end-star)+"毫秒数");
    }
}


